local _G = _G
local LibKeyBound = LibStub("LibKeyBound-1.0")
local AceEvent = LibStub("AceEvent-3.0")
local Button = CreateFrame("Button")
local Button_MT = {__index = Button}

Yata.Button = {}
Yata.Button.prototype = Button
Yata.Button.db = Yata.db

function Yata.Button:CreateBase(id, parent)
	local name = "YataTotemButton" .. id
	local button = _G[name] or setmetatable(CreateFrame("Button", name, parent, "SecureHandlerEnterLeaveTemplate, SecureHandlerAttributeTemplate, SecureActionButtonTemplate"), Button_MT)
	button.Id = id
	button.Parent = parent
	button.Name = name
	button:SetWidth(36)
	button:SetHeight(36)	
	button:RegisterForClicks("LeftButtonUp","RightButtonUp")		
	
	button:HookScript("OnEnter", function() button:OnEnter(button) end)
	button:HookScript("OnLeave", function() button:OnLeave() end)
	
	button.Icon = button.Icon or button:CreateTexture(name.."Icon")   
	button.Icon:SetAllPoints(button)
	
	button:SetPushedTexture("Interface\\Buttons\\UI-Quickslot-Depress")
	button:SetHighlightTexture("Interface\\Buttons\\ButtonHilight-Square")
	button:GetHighlightTexture():SetBlendMode("ADD")
	
	button.Cooldown = button.Cooldown or CreateFrame("Cooldown", name.."Cooldown",button,"CooldownFrameTemplate")
	button.Cooldown:SetWidth(36)
	button.Cooldown:SetHeight(36)
	button.Cooldown:SetPoint("CENTER",0,-1)
	
	button.HotKey = button.HotKey or button:CreateFontString(name.."HotKey", "OVERLAY", "NumberFontNormalSmallGray")
	button.HotKey:SetWidth(36)
	button.HotKey:SetHeight(10)
	button.HotKey:SetJustifyH("RIGHT")
	button.HotKey:SetPoint("TOPLEFT",-2,-2)	
	
	button:SetNormalTexture("")	
	button.NormalTexture = button:GetNormalTexture()
	button.NormalTexture:SetWidth(66)
	button.NormalTexture:SetHeight(66)
	button.NormalTexture:ClearAllPoints()
	button.NormalTexture:SetPoint("CENTER", 0, -1)
	button.NormalTexture:Hide()

	button.Duration = button.Duration or button:CreateFontString(name.."Duration", "BACKGROUND", "GameFontNormalSmall")
	button.Duration:SetPoint("TOP",parent,"BOTTOM",0,0)	
	
	button:RegisterEvents()
	button:UpdateHotkey()	
	return button
end


function Yata.Button:Create(id, parent, totem)
	local button = Yata.Button:CreateBase(id,parent)
	button.Totem = totem
	button:SetParent(parent)
	button:SetAttribute( "_onenter", [[  
		header:SetAttribute("show", true)
	]] )
	button:SetAttribute( "_onleave", [[  
		inHandler = header:IsUnderMouse(true)
		if not inHandler then			
			header:SetAttribute("show", false)
		end	    
	]] )
	button:SetAttribute( "_onattributechanged", [[
		if name == "newposition" then
			self:ClearAllPoints()
			self:SetAttribute("position", value)
			local orientation = header:GetAttribute("orientation")
			local proxybinding = header:GetAttribute("proxybinding")
			local anchor, xpos, ypos
			if orientation == 1 then
				anchor = "BOTTOM"
				xpos = 0
				ypos = value*(36 + header:GetAttribute("buttongap") or 0)
			elseif orientation == 2 then
				anchor = "TOP"		
				xpos = 0
				ypos = -value*(36 + header:GetAttribute("buttongap") or 0)
			end
			if proxybinding then
				if value == 0 then
					self:SetBindingClick(1,proxybinding,self)
				else
					self:ClearBinding(proxybinding)
				end
			end
			self:SetPoint( anchor , header, anchor, xpos, ypos)
			if self:GetAttribute("position") < header:GetAttribute("visiblebuttons")then
				self:Show()
			else
				self:Hide()
			end
		end
	]] )
	button:Execute([=[checkModifier = [[
		if (key == "shift" and IsShiftKeyDown())
		or (key == "alt" and IsAltKeyDown())
		or (key == "ctrl" and IsControlKeyDown()) then
			return true
		else
			return false
		end
		]]
	]=] )
	button:Execute([=[swapButton = [[
		pos = self:GetAttribute("position")
		if pos > 0 then
			local buttonSize = header:GetAttribute("buttongap") + 36
			children = newtable(header:GetChildren())
			for i,b in ipairs(children) do			
				local oldpos = b:GetAttribute("position")
				local newpos = oldpos
				if oldpos < pos then
					newpos = oldpos + 1
				elseif oldpos == pos then
					newpos = 0
				end
				b:SetAttribute("newposition",newpos)
			end
		end
		header:SetAttribute("show",false)	
		]]
	]=] )
	button:SetAttribute("hidden", false)
	return button		
end

function Yata.Button:CreateHeader(id, parent)
	local name = "YataElementHeader" .. id
	local header = _G[name] or CreateFrame("Frame", name, parent, "SecureHandlerAttributeTemplate, SecureHandlerEnterLeaveTemplate")
	header.Name = name
	header.Parent = parent;
	header:SetWidth(36)
	header:SetHeight(0)	
	--[[
	header.Texture = header:CreateTexture()
	header.Texture:SetTexture(0, 0, 0.5, 1)
	header.Texture:SetAllPoints(header)	
	--]]
	header:SetAttribute("proxybinding",nil)
	header:SetAttribute("element",id)
	header:SetAttribute("_onattributechanged", [[
		local buttongap = self:GetAttribute("buttongap") or 0
		local headerSize = 36
		local buttonSize = headerSize + buttongap
		if name == "show" then
			local visibleButtons = self:GetAttribute("visiblebuttons") or 1
			buttons = newtable(self:GetChildren())
			if value == true then
				for k,v in ipairs(buttons) do 
					if not v:GetAttribute("hidden") or v:GetAttribute("position") == 0 then
						v:Show()
					end
				end
				headerSize = buttonSize * (#buttons - 1) + headerSize
			else
				for k,v in ipairs(buttons) do 
					local pos = v:GetAttribute("position")
					if pos < visibleButtons then
						v:Show()
					else
						v:Hide()
					end
				end
			end
			self:SetHeight(headerSize)
		elseif name == "position" then
			local orientation = self:GetAttribute("orientation")
			local anchor = nil
			if orientation == 1 then
				anchor = "BOTTOMLEFT"
			elseif orientation == 2 then
				anchor = "TOPLEFT"
			end
			self:ClearAllPoints()
			self:SetPoint(anchor, self:GetParent(),anchor,value*buttonSize,0)
		end
	]] )
	return header
end

function Yata.Button:CreateTotemProxy(id,parent)
	local name = "YataTotemProxy" .. id
	local button = Yata.Button:CreateBase(id,parent)	
	button.Totem = {}
	button.Totem.Name = name
	button.Title = button.Title or button:CreateFontString(name.."Title", "OVERLAY", "NumberFontNormal")
	button.Title:SetWidth(36)
	button.Title:SetHeight(10)
	button.Title:SetText(id)
	button.Title:SetPoint("CENTER",0,-10)	
	return button
end

function Button:SetOnClickScript(autobutton)
	if autobutton then
		self:UnwrapScript(self,"OnClick")
		self:WrapScript(self,"OnClick",[[
			if button == "LeftButton" then
				key = self:GetAttribute("swapkey")
				if control:Run(checkModifier,key) then
					control:Run(swapButton)
					return false
				end
				return nil, true
			end
		]], [[
			if button == "LeftButton" then
				key = self:GetAttribute("noswapkey")
				if not control:Run(checkModifier,key) then
					control:Run(swapButton)
				end
			end
		]] )
	else
		self:UnwrapScript(self,"OnClick")
		self:WrapScript(self,"OnClick","return nil, true", [[header:SetAttribute("show",false)]])
	end	
end

function Button:RegisterEvents()
	AceEvent.RegisterEvent(self,"UPDATE_BINDINGS")
	AceEvent.RegisterEvent(self,"SPELL_UPDATE_USABLE")
end

function Button:UPDATE_BINDINGS()
	self:UpdateHotkey()
end

function Button:SPELL_UPDATE_USABLE()
	if not self.Totem then return end
	local usable, nomana = IsUsableSpell(self.Totem.Name)
	if(usable) then
		self.Icon:SetVertexColor(1.0,1.0,1.0)
	elseif(nomana) then
		self.Icon:SetVertexColor(0.1, 0.3, 1.0)
	else
		self.Icon:SetVertexColor(0.4,0.4,0.4)
	end
end

function Button:OnEnter(self)
	if Yata.db.profile.ShowTooltip then
		self:SetTooltip()
	end	
	LibKeyBound:Set(self)
end

function Button:OnLeave()
	GameTooltip:Hide()
end

function Button:GetHotkey()
	local key1 = GetBindingKey(format("CLICK %s:LeftButton", self.Name))
	local displayKey = LibKeyBound:ToShortKey(key1)
	return displayKey
end

function Button:UpdateHotkey()
	local key = self:GetHotkey()
	local hotkey = self.HotKey
	if key then
		hotkey:SetText(key)
		hotkey:Show()
	end
end

function Button:GetActionName()
	return self.Totem.Name
end


function Button:SetTooltip()
	if  GetCVar("UberTooltips") == "1"  then
		GameTooltip_SetDefaultAnchor(GameTooltip, self)
	else
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
	end
	if Yata.db.profile.ShortTooltip then
		GameTooltip:SetText(self.Totem.Name, 1.0, 1.0, 1.0)
	elseif self.Totem.SpellID then
		GameTooltip:SetHyperlink(GetSpellLink( self.Totem.SpellID, BOOKTYPE_SPELL ))
	end
end
